#include "filefilter.h"
#include <QDir>
#include <QFileInfo>
#include <iostream>
#include <QProcess>

namespace Yzty
{
    FileFilter* Yzty::FileFilter::_instance=nullptr;

    FileFilter* FileFilter::GetInstance(QObject *parent)
    {
        if(FileFilter::_instance==nullptr)
            FileFilter::_instance=new FileFilter(parent);
        return FileFilter::_instance;
    }

    FileFilter::FileFilter(QObject* parent):QObject (parent)
    {
        _filecnts.store(0);           //初始化过滤条件
    }

    FileFilter::~FileFilter()
    {

    }

    void FileFilter::SetFilterConditon(const Yzty::FileCheckCondition &condition)
    {
        this->_condition=condition;
        this->_allfiles.clear();
        this->_files.clear();
        this->Absfilenumbers();
    }

    const QFileInfoList& FileFilter::GetSelectAblePaths(Yzty::FileTypeLimit::Type type)
    {
        return this->_files[type];
    }

    WordLibCode FileFilter::GetWordLib()
    {
        return this->_condition._keywordlimit._marks;
    };

    const Yzty::FileCheckCondition& FileFilter::GetFilterCondition()
    {
        return this->_condition;
    }

    void FileFilter::Filter()
    {
        /*
         * 1. 路径上过滤
         * 2. 类型上过滤
         * 3. 大小上过滤
         * 4. 时间上过滤
         */
        PathFilter();
        TypeFilter();
        SizeFilter();
        TimeFilter();

        KeyWordFilter();    //关键词过滤

        emit FinishFilter(); //过滤完成消息通知
    }

    void FileFilter::PathFilter()
    {
        DirLimit& dlimit=this->_condition._dirlimit;
        QDir::Filters flag=QDir::AllDirs|QDir::Files|QDir::NoDotAndDotDot|QDir::Readable;
        /*
         * １.所有文件夹（文件夹不受过滤字段的影响）
         * ２.所有文件
         * ３.不含 ./ 和　../
         * ４.所有可读文件
        */
   //     this->Absfilenumbers();
        for(QDir& dir:dlimit._dirs)
            _pathfilter(dir,flag);
    }

    void FileFilter::_pathfilter(const QDir &dir,QDir::Filters flag)
    {

        for(QFileInfo& infor:dir.entryInfoList(flag))
        {
            if(infor.isDir())
                _pathfilter(infor.filePath(),flag);                          //递归遍历当前目录下的所有文件
            else if(infor.isFile())
                this->_allfiles.push_back(infor);
        }
    }

    void FileFilter::TypeFilter()
    {
        FileTypeLimit& typelimit=_condition._typelimit;
        for(int i=0;i<63;++i)
        {
            if((typelimit._marks>>i)&1)
            {
                for(QFileInfo& infor:_allfiles)
                {
                    if(infor.suffix()==FileTypeLimit::TypeNames[i]){
                        _files[FileTypeLimit::Type(int64_t(1)<<i)].append(infor);    //添加到相同的类型中
                        std::cout<<infor.filePath().toStdString()<<std::endl;
                    }
                }
            }
        }
    }

    void FileFilter::SizeFilter()
    {
        SizeLimit& sizelimit=_condition._sizelimit;
        if(sizelimit._model&SizeLimit::NoLimit)        //无限制
            return;

        for(auto key:_files.keys())
        {
            QVector<QList<QFileInfo>::Iterator> temp;
            for(auto iter=_files[key].begin();iter!=_files[key].end();++iter)
            {
                if(iter->size()<sizelimit._lowlimit||iter->size()>sizelimit._uplimit)
                    temp.push_back(iter);
            }

            for(auto iter:temp)             //延后移除
                _files[key].erase(iter);
        }
    }

    void FileFilter::TimeFilter()
    {
        TimeLimit& timelimit=_condition._timelimit;

        if(timelimit._model&TimeLimit::NoLimit)
            return;

        for(auto key:_files.keys())
        {
            QVector<QList<QFileInfo>::Iterator> temp;
            for(auto iter=_files[key].begin();iter!=_files[key].end();++iter)
            {
                if((timelimit._model&timelimit.Create)&&            //创建时间限制
                        (timelimit._start_create_time>iter->birthTime()||iter->birthTime()>timelimit._end_create_time))
                    temp.push_back(iter);
                else if((timelimit._model&TimeLimit::Modify)&&      //修改时间限制
                        (timelimit._start_modify_time>iter->lastModified()||iter->lastModified()>timelimit._end_modify_time))
                    temp.push_back(iter);

            }

            for(auto iter:temp)             //延后移除
                _files[key].erase(iter);
        }
    }

    void FileFilter::KeyWordFilter()
    {
        this->_keywordlibs=_condition._keywordlimit._marks;
    }

    const QMap<Yzty::FileTypeLimit::Type,QFileInfoList>& FileFilter::GetAllSelectAblePahts()
    {
        return this->_files;
    }

    const QVector<QDir> FileFilter::Getdirpaths() {
        return this->_condition._dirlimit._dirs;
    }


   void FileFilter::Absfilenumbers(){
/*       QProcess process;
       for(int i=0;i<FileFilter::GetInstance()->Getdirpaths().size();i++){
           QString dir=FileFilter::GetInstance()->Getdirpaths()[i].path();
           process.start("cd"+dir);
           process.start("ls -lR|wc -l");
           process.waitForFinished();
           int tmp = process.readAllStandardOutput().toUInt();

           _filecnts +=tmp;
       }
*/
       QVector<QDir> dirs=Getdirpaths();
       this->_filecnts.store(0);
       for(QDir tmp:dirs){
             QString str=tmp.path();
             QString cmd="ls -lR "+str+ " |grep '^-'|wc -l";
             FILE* fp=popen(cmd.toLocal8Bit(),"r");          //获取命令行输出
             if(fp==nullptr)
                  return;
             QTextStream fstream(fp);
             QString temp=fstream.readAll().simplified();
             _filecnts +=temp.toUInt();
        }
    }


    int FileFilter::getAbsfilenumbers(){
         return _filecnts;
    }
}
